package cn.gov.pbc.gd.credit.core.service.work.add.impl;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.liu.jbase.PageListVo;
import com.liu.jbase.ResultVo;
import com.liu.jbase.service.impl.BaseServiceImpl;
import com.liu.tools.LogUtil;
import com.liu.tools.PrimaryUtil;
import com.liu.tools.StrUtil;

import cn.gov.pbc.gd.credit.api.notice.INoticeApi;
import cn.gov.pbc.gd.credit.api.work.IWorkApi;
import cn.gov.pbc.gd.credit.api.work.add.IAddApi;
import cn.gov.pbc.gd.credit.common.constant.CodeConstant;
import cn.gov.pbc.gd.credit.common.constant.CommonConstant;
import cn.gov.pbc.gd.credit.common.model.UserModel;
import cn.gov.pbc.gd.credit.common.service.redis.IRedisService;
import cn.gov.pbc.gd.credit.common.util.UserUtil;
import cn.gov.pbc.gd.credit.core.service.work.add.IAddService;
import cn.gov.pbc.gd.credit.vo.notice.NoticeVo;
import cn.gov.pbc.gd.credit.vo.work.ResWorkVo;
import cn.gov.pbc.gd.credit.vo.work.WorkVo;
import cn.gov.pbc.gd.credit.vo.work.add.AddVo;
import cn.gov.pbc.gd.credit.vo.work.add.ResAddVo;

/**
 * 表个中的
 * 
 * @author Administrator
 *
 */
@Service
public class AddServiceImpl extends BaseServiceImpl<ResAddVo, AddVo, IAddApi> implements IAddService {

	private static Logger logger = LoggerFactory.getLogger(AddServiceImpl.class);
	
	@Autowired
	private IAddApi addApi;

	@Autowired
	private IWorkApi workApi;
	
	@Autowired
	private IRedisService redisService;
	
	private Executor executor = Executors.newFixedThreadPool(3);

	@Autowired
	private INoticeApi noticeApi;
	
	@Override
	public ResultVo<ResAddVo> add(AddVo record, HttpServletRequest request) {

		ResultVo<ResAddVo> res = new ResultVo<ResAddVo>();

		res.setCode(CodeConstant.SUCCESS);

		UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
		
		// 将前台传过来的8位数字，转换为日期格式，传到对象中。
		Date date = getDateForString(record.getStrDate());
		
		//设置日期
		record.setDay(date);
		record.setCorpId(userModel.getCorpId());
		record.setStatus(1);
		record.setApplyTime(new Date());
		record.setProposerId(userModel.getUserId());
		record.setUserId(record.getWorkUserId());
		record.setAddType(getAddType(record));
		record.setId(PrimaryUtil.primaryId("I"));
		
		//新建一个AddVo对象，用于查询当前日期是否存有数据
		AddVo addVo = new AddVo();
		addVo.setDay(date);
		addVo.setCorpId(userModel.getCorpId());
		List<ResAddVo> list = addApi.list(addVo);
		
		if(list.size() > 0){
			
			for (ResAddVo resAddVo : list) {
				if(resAddVo.getStatus() != 3){
					if (resAddVo.getAddType() == CommonConstant.ADD_TYPE_CORP) {
						
						logger.info(LogUtil.msg("AddServiceImpl:add", "该加班信息已存在，不再重复添加, req:" + JSON.toJSONString(record)));
						return res;
					}
					
					if (resAddVo.getAddType() == CommonConstant.ADD_TYPE_DEPT) {
						if(resAddVo.getDeptId().equals(record.getDeptId())){
							logger.info(LogUtil.msg("AddServiceImpl:add", "该加班信息已存在，不再重复添加, req:" + JSON.toJSONString(record)));
							return res;
						}
					}
					
					if (resAddVo.getAddType() == CommonConstant.ADD_TYPE_USER) {
						if(resAddVo.getUserId().equals(record.getUserId())){
							logger.info(LogUtil.msg("AddServiceImpl:add", "该加班信息已存在，不再重复添加, req:" + JSON.toJSONString(record)));
							return res;
						}
					}
				}
			}
		}

		try {
			
			int flag = addApi.insert(record);
			if(flag == 0){
				logger.info(LogUtil.msg("AddServiceImpl:add", "添加加班信息失败, req:" + JSON.toJSONString(record)));
				res.setCode(CodeConstant.FAIL);
				res.setMsg("添加数据失败");
				return res;
			}
			upDateWorkVo(record, request);// 修改upDateWorkVo中，对应日期的isWork值
			
			executor.execute(new Runnable() {
				
				@Override
				public void run() {
					//添加新用户成功后在notice表插入新数据等待审核
					NoticeVo noticeVo=new NoticeVo();
					noticeVo.setId(PrimaryUtil.primaryId("R"));
					noticeVo.setSourceId(record.getId());
					noticeVo.setCorpId(userModel.getCorpId());
					noticeVo.setContent(userModel.getAccount() +"的加班申请");
					//noticeVo.setNoticeUserId(noticeUserId);
					noticeVo.setNoticeType(CommonConstant.NOTICE_TYPE_ADD_WORK);
					noticeVo.setNoticeFlag(1);
					noticeVo.setStatus(1);
					noticeVo.setApproveStatus(0);
					noticeVo.setCreateBy(userModel.getUserId());
					noticeVo.setCreateTime(new Date());
					noticeVo.setUpdateBy(userModel.getUserId());
					noticeVo.setUpdateTime(new Date());
					
					try {
						noticeApi.insert(noticeVo);
					} catch (Exception e) {
						logger.error(LogUtil.msg("UserServiceImpl:add", "添加通知信息异常"), e);
					}
					
				}
			});
			
		} catch (Exception e) {
			logger.info(LogUtil.msg("AddServiceImpl:add", "添加加班信息异常, req:" + JSON.toJSONString(record)), e);
			res.setCode(CodeConstant.FAIL);
			res.setMsg("添加数据失败");
			return res;
		}
		
		

		return res;
	}

	private int getAddType(AddVo vo){
		
		if(StrUtil.isNotNull(vo.getUserId()) && ! "-1".equals(vo.getUserId())){
			return CommonConstant.ADD_TYPE_USER;
		}
		
		if(StrUtil.isNotNull(vo.getDeptId()) && ! "-1".equals(vo.getDeptId())){
			return CommonConstant.ADD_TYPE_DEPT;
		}
		
		return CommonConstant.ADD_TYPE_CORP;
		
	}
	
	/**
	 * 通过日期查询workVo对应的表，当前工作日状态是否和iswork相同 不同返回flase,相同返回true
	 * 
	 * @param date
	 * @param isWork
	 * @return
	 */
	private void upDateWorkVo(AddVo record, HttpServletRequest request) {


		WorkVo workVo = new WorkVo();	// 新建查询条件类

		workVo.setDay(record.getDay());	// 设置日期，根据日期查询
		//workVo.setIsAddWork(1);
		List<ResWorkVo> list = workApi.list(workVo);	// list查询

		if (list.size() > 0) {

			int workVoIsWork = list.get(0).getIsWork();	// 查询当天工作日情况

			if (workVoIsWork != record.getIsWork()) {	// 如果是工作日，则修改

				WorkVo workVoUpdate = new WorkVo();

				workVoUpdate.setIsAddWork(1);	// 设置加班

				workVoUpdate.setId(list.get(0).getId());	// 设置ID

				workApi.update(workVoUpdate);	// 更新工作日数据

			}

		}

	}

	/**
	 * 
	 * @param strDate
	 *            8位数字（字符串格式）
	 * @return 将8位字符串数字转换为日期格式，如：20121212-->2012.12.12。
	 *         如果输入的字符串格式不正确或者为null,输出日期为2017.1.1
	 */
	private static Date getDateForString(String strDate) {

		if (strDate == null || strDate == "") {

			strDate = "20170101"; // 如果传入为空，则赋值：20170101

		}

		LocalDateTime localDateTime = null;

		Pattern pattern = Pattern.compile("[0-9]{8}"); // 正则，8位纯数字

		Matcher isNum8 = pattern.matcher(strDate);

		if (isNum8.matches()) { // 如果字符串为，8位纯数字，则添加时分秒，并转换为LocalDateTime格式的时间

			strDate += "000000";

			localDateTime = LocalDateTime.parse(strDate, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

		} else {

			localDateTime = LocalDateTime.of(2017, 1, 1, 0, 0); // 字符串不是8位数字，则设置时间为2017.1.1

		}

		// 将LocalDateTime转换为Date格式输出
		ZoneId zone = ZoneId.systemDefault();

		Instant instant = localDateTime.atZone(zone).toInstant();

		Date date = Date.from(instant);

		return date;
	}
	
	@Override
	public ResultVo<PageListVo<ResAddVo>> page(AddVo record, PageListVo<ResAddVo> page, HttpServletRequest request) {
		
		if(record.isMyself()){
			UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
			record.setUserId(userModel.getUserId());
		}
		
		UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
		record.setCorpId(userModel.getCorpId());
		
		return super.page(record, page, request);
	}
}
